package com.mco.service;

import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.RandomUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * @author ：liao.wei
 * @date ：2023/10/7 19:01
 * @package : com.mco.service
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class RedPackageService {
	
	private final RedisTemplate<String, Object> template;
	
	
	public static final String RED_PACKAGE_KEY = "red_package:";
	
	public static final String RED_PACKAGE_CONSUME_KEY = "red_package:consume";
	
	public BigDecimal[] sendPackage(String key, Double totalMoney, int redPackageNumber) {
		// 1. 拆红包，将总金额totalMoney拆成redPackageNumber个红包
		BigDecimal[] splitRedPackage = splitRedPackageAlgorithm(totalMoney, redPackageNumber);
		
		// 2. 发红包将红包赛进redis,设置过期实际
		template.opsForList().leftPushAll(RED_PACKAGE_KEY + key, splitRedPackage);
		template.expire(RED_PACKAGE_KEY + key, 1, TimeUnit.DAYS);
		return splitRedPackage;
	}
	
	/**
	 * 拆红包算法--二倍均值算法
	 *
	 * @param totalMoney       总金额
	 * @param redPackageNumber 红包个数
	 * @return 红包数组
	 */
	private BigDecimal[] splitRedPackageAlgorithm(Double totalMoney, int redPackageNumber) {
		BigDecimal[] redPackageNumbers = new BigDecimal[redPackageNumber];
		
		// 已经被拆分的金额
		BigDecimal userMoney = new BigDecimal(0);
		for (int i = 0; i < redPackageNumber; i++) {
			if (i == redPackageNumber - 1) {
				redPackageNumbers[i] = NumberUtil.sub(totalMoney, userMoney);
			} else {
				// 二倍均值算法 每次拆分后塞进子红包的金额=随即区间（0，(剩余红包金额➗未赛红包个数)✖2）
				BigDecimal avgMoney = NumberUtil.round(NumberUtil.mul(NumberUtil.div(NumberUtil.sub(totalMoney, userMoney), (redPackageNumber - i)), 2), 2);
				redPackageNumbers[i] = NumberUtil.round(RandomUtil.randomBigDecimal(new BigDecimal("0.01"), avgMoney),2);
			}
			userMoney = NumberUtil.add(userMoney, redPackageNumbers[i]);
		}
		return redPackageNumbers;
	}
	
	public String robPackage(String redPackageKey, String userId) {
		// 1. 验证某个用户释放抢过红包，不可以多抢
		String key = RED_PACKAGE_CONSUME_KEY + userId;
		Object redPackage = template.opsForHash().get(RED_PACKAGE_CONSUME_KEY + redPackageKey, userId);
		// 没有就去抢
		if (Objects.isNull(redPackage)) {
			// 从红包队列中弹出一次
			BigDecimal partRedPackage = (BigDecimal) template.opsForList().leftPop(RED_PACKAGE_KEY + redPackageKey);
			if (Objects.nonNull(partRedPackage)) {
				// 记录红包记录
				template.opsForHash().put(RED_PACKAGE_CONSUME_KEY + redPackageKey, userId, partRedPackage);
				System.out.printf("用户: %s 抢到了 %s 的红包%n", userId, partRedPackage);
				// TODO 后续业务，业务统计
				return String.valueOf(partRedPackage);
			}
			// 抢完了
			return "抢完了";
		}
		//已抢过了
		return "您已经抢过红包了！";
	}
}
